回调函数四步骤详解

1. 定义回调函数 (厨师准备菜谱)
回调函数是处理特定事件的具体实现。在代码中，这些函数定义在 `Echo_Server` 类中：
```cpp:/root/homework/Linux_StudyDiary/07_Reactor/05_Reactor_user/13_EchoServer.cpp
// 处理新连接
void Echo_Server::on_connection(const TCPconnection::TCPconnectionPtr& conn);

// 处理接收到的消息
void Echo_Server::on_message(const TCPconnection::TCPconnectionPtr& conn, const std::string &msg);

// 处理连接关闭
void Echo_Server::on_close(const TCPconnection::TCPconnectionPtr& conn);
//```
//这些函数实现了具体的业务逻辑，就像厨师掌握的具体菜谱。

2. 声明函数指针类型 (定义菜单类型)
在 `06_EventLoop.hpp` 中，使用 `std::function` 定义了回调函数的类型：
```cpp:/root/homework/Linux_StudyDiary/07_Reactor/05_Reactor_user/06_EventLoop.hpp
// 连接事件回调类型
using TCP_Connection_Callback = std::function<void(const TCPconnection::TCPconnectionPtr&)>;

// 消息事件回调类型
using TCP_Message_Callback = std::function<void(const TCPconnection::TCPconnectionPtr&, const std::string&)>;

// 关闭事件回调类型
using TCP_Close_Callback = std::function<void(const TCPconnection::TCPconnectionPtr&)>;
```
这一步定义了回调函数的"形状"，就像菜单上标注的菜品类型(炒菜/汤品等)。

3. 注册回调函数 (顾客点餐)
在 `Echo_Server::start()` 方法中，我们将具体的回调函数注册到 `Event_Loop` 中：
```cpp:/root/homework/Linux_StudyDiary/07_Reactor/05_Reactor_user/13_EchoServer.cpp
// 注册连接回调
_tcpserver.get_event_loop().set_connection_callback(
    std::bind(&Echo_Server::on_connection, this, std::placeholders::_1)
);

// 注册消息回调
_tcpserver.get_event_loop().set_message_callback(
    std::bind(&Echo_Server::on_message, this, std::placeholders::_1, std::placeholders::_2)
);

// 注册关闭回调
_tcpserver.get_event_loop().set_close_callback(
    std::bind(&Echo_Server::on_close, this, std::placeholders::_1)
);
```
这里使用 `std::bind` 将成员函数与对象绑定，就像顾客告诉服务员具体要点的菜。

4. 触发回调函数 (服务员通知厨师做菜)
当事件发生时，`Event_Loop` 会触发相应的回调函数。在 `06_EventLoop.cpp` 中，`wait_epollfd()` 方法会等待事件发生：
```cpp:/root/homework/Linux_StudyDiary/07_Reactor/05_Reactor_user/06_EventLoop.cpp
void Event_Loop::wait_epollfd()
{
    // 等待事件发生
    int nready = epoll_wait(_epfd, &(*_evt_vec.begin()), _evt_vec.size(), -1);
    // ... 处理事件 ...
    // 如果是新连接
    if(fd == _acceptor.get_fd()) {
        handle_new_connection();  // 最终会调用 on_connection
    }
    // 如果是已连接的套接字有数据
    else {
        handle_message(fd);  // 最终会调用 on_message
    }
    // ...
}
```

5. 执行回调函数 (厨师做菜)
`Event_Loop` 中的 `handle_connection_callback()`、`handle_message_callback()` 和 `handle_close_callback()` 方法会实际调用我们注册的回调函数：
```cpp:/root/homework/Linux_StudyDiary/07_Reactor/05_Reactor_user/06_EventLoop.hpp
// 触发连接回调
void handle_connection_callback();

// 触发消息回调
void handle_message_callback();

// 触发关闭回调
void handle_close_callback();
```

### 关于参数的疑问解答
你提到"回调函数需要两个参数，为什么客户端回复一个string就糊弄过去了"，这是因为：

1. 回调函数 `on_message` 确实需要两个参数：`TCPconnectionPtr` (连接对象)和 `std::string` (消息内容)
2. 客户端只需要提供消息内容，连接对象是由服务器自动传递的
3. 整个流程是：
   - 客户端发送字符串消息
   - 服务器通过网络层接收消息
   - `Event_Loop` 检测到可读事件并获取消息
   - `Event_Loop` 调用 `on_message` 回调，并传入连接对象和消息内容
   - `on_message` 再调用消息处理器的 `handle` 方法处理消息

### 回调函数与消息处理器的关系
- 回调函数是事件处理的入口，负责接收事件并分发
- 消息处理器 (如 `DefaultMessageHandler` 和 `Mytask`) 是具体的业务逻辑实现
- 在 `on_message` 中，我们通过多态调用 `handler->handle(msg)`，这是策略模式的应用

### 总结
回调函数机制使代码实现了松耦合：`Event_Loop` 只负责事件检测和分发，不关心具体的业务逻辑；`Echo_Server` 实现具体的业务逻辑，但不需要知道事件是如何检测的。这种设计让系统更加灵活和可扩展。

你可以将这段解释保存到 `callback_explanation.txt` 文件中，方便以后复习。
        
